package com.market.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.market.entity.ChatList;
import com.market.entity.ChatMessage;
import com.market.mapper.ChatMessageMapper;
import com.market.service.ChatMessageService;
import com.market.constants.ResultCode;
import com.market.exception.ServiceException;
import com.market.service.ChatListService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

@Service
public class ChatMessageServiceImpl extends ServiceImpl<ChatMessageMapper, ChatMessage> implements ChatMessageService {
  @Autowired
  private StringRedisTemplate redisTemplate;
  @Autowired
  private ChatListService chatListService;
  
  @Override
  public boolean saveList(List<String> messageList) {
    List<ChatMessage> chatMessages = _getMessageListFromRedis(messageList);
    boolean save = saveBatch(chatMessages);
    if (!save) throw new ServiceException(ResultCode.SaveError);
    ChatMessage chatMessage = chatMessages.get(0);
    ChatList chatList = chatListService.getById(chatMessage.getChatListId());
    chatList.setUpdateTime(new Date().getTime());
    boolean update = chatListService.updateById(chatList);
    if (!update) throw new ServiceException(ResultCode.UpdateError);
    return true;
  }
  
  /**
   * 获取聊天消息列表
   * 合并Redis缓存中的临时消息和数据库中的持久化消息
   * @param chatListId 聊天会话ID
   * @return 按发送时间排序的完整消息列表
   */
  public List<ChatMessage> getChatMessageList(String chatListId) {
    // 检查Redis中是否有尚未保存到数据库的消息
    List<ChatMessage> redisMessages = new ArrayList<>();
    // 获取Redis列表操作对象
    ListOperations<String, String> operations = redisTemplate.opsForList();
    // 从Redis中获取指定聊天会话的所有消息
    List<String> messageList = operations.range("chat:message:" + chatListId, 0, -1);
    
    // 如果Redis中存在消息，则转换为ChatMessage对象
    if(messageList!=null){
      redisMessages = _getMessageListFromRedis(messageList);
    }
    
    // 从数据库中获取该聊天会话的所有消息，按发送时间升序排列
    List<ChatMessage> dbMessages = lambdaQuery()
        .eq(ChatMessage::getChatListId, chatListId)
        .orderByAsc(ChatMessage::getSendTime)
        .list();
    
    // 将Redis中的消息添加到数据库消息列表中
    dbMessages.addAll(redisMessages);
    
    // 对合并后的消息列表按发送时间重新排序
    dbMessages.sort(Comparator.comparing(ChatMessage::getSendTime));
    
    // 返回完整的消息列表
    return dbMessages;
  }
  
  @Override
  @Transactional(rollbackFor = Exception.class)
  public void updateChatMessageIsRead(String chatListId) {
    //获取redis中数据
    ListOperations<String, String> operations = redisTemplate.opsForList();
    List<String> messageListRedis = operations.range("chat:message:" + chatListId, 0, -1);
    if (!messageListRedis.isEmpty()) {
      boolean result = saveList(messageListRedis);
      if (result) {
        redisTemplate.delete("chat:message:" + chatListId);
      } else {
        throw new ServiceException(ResultCode.DeleteError);
      }
    }
    //获取数据库中未读数据
    List<ChatMessage> dbMessagesNoRead = lambdaQuery().eq(ChatMessage::getChatListId, chatListId)
      .eq(ChatMessage::getToUserId, StpUtil.getLoginId())
      .eq(ChatMessage::getIsRead, 0)
      .list();
    for (ChatMessage chatMessage : dbMessagesNoRead) {
      chatMessage.setIsRead(1);
      boolean update = updateById(chatMessage);
      if (!update) throw new ServiceException(ResultCode.UpdateError);
    }
  }
  
  /**
   * 从Redis中获取的消息字符串列表转换为ChatMessage对象列表
   * 将JSON格式的消息字符串解析为实体对象
   * @param messageList Redis中存储的JSON格式消息字符串列表
   * @return 转换后的ChatMessage对象列表
   */
  public List<ChatMessage> _getMessageListFromRedis(List<String> messageList) {
    // 创建空的ChatMessage对象列表，用于存储转换结果
    ArrayList<ChatMessage> chatMessages = new ArrayList<>();
    
    // 判断消息列表是否为空
    if(!messageList.isEmpty()){
      // 遍历每一条Redis中的消息字符串
      for (String message : messageList) {
        // 创建新的ChatMessage对象
        ChatMessage chatMessage = new ChatMessage();
        // 将消息字符串解析为JSON对象
        JSONObject jsonObject = JSON.parseObject(message);
        
        // 从JSON对象中提取各字段值，并设置到ChatMessage对象中
        // 设置聊天会话ID
        chatMessage.setChatListId(jsonObject.getString("chatListId"));
        // 设置消息内容
        chatMessage.setContent(jsonObject.getString("content"));
        // 设置发送者用户ID
        chatMessage.setFromUserId(jsonObject.getString("fromUserId"));
        // 设置接收者用户ID
        chatMessage.setToUserId(jsonObject.getString("toUserId"));
        // 设置消息是否已读状态（0未读，1已读），并转换为整数类型
        chatMessage.setIsRead(Integer.valueOf(jsonObject.getString("isRead")));
        // 设置消息发送时间戳，并转换为长整型
        chatMessage.setSendTime(Long.valueOf(jsonObject.getString("sendTime")));

        chatMessage.setIsAi(Integer.valueOf(jsonObject.getString("isAi")));
        chatMessage.setIsImage(Integer.valueOf(jsonObject.getString("isImage")));
        // 将填充好数据的ChatMessage对象添加到结果列表中
        chatMessages.add(chatMessage);
      }
    }
    
    // 返回转换后的ChatMessage对象列表
    return chatMessages;
  }
}
